package com.dabai.dbutils.manager;

import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Build;

/**
 * Android音频焦点 管理器
 */
public class AudioFocusManager implements AudioManager.OnAudioFocusChangeListener {
    private AudioManager mAudioManager;
    private AudioFocusRequest mFocusRequest;
    private AudioAttributes mAudioAttributes;

    private onRequestFocusResultListener mOnRequestFocusResultListener;
    private OnAudioFocusChangeListener mAudioFocusChangeListener;


    /**
     * 使用前 先实例化一个焦点对象出来
     * 后续用这个实例 调用方法
     * @param context
     */
    public AudioFocusManager(Context context) {
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    }

    /**
     * 请求焦点 传入模式 (共4种)
     *
     *         AudioManager.AUDIOFOCUS_GAIN: API文档说请求的这类音频焦点持续时间是未知的，通常用来表示长时间获取焦点，可以用来播放音乐，录音等等。
     *         AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: 表明请求的音频焦点持续时间比较短，通常用来播放导航路线的声音，或者播放通知声音。
     *         AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: 这个也是表明请求的音频焦点持续时间比较短，但是在这段时间内，它希望其他应用以较低音量继续播放。例如，我们在使用导航的时候可以听音乐，当出现导航语音的时候，音乐音量会降低以便我们能听清楚导航的语音，当导航语音播放完毕后，音乐恢复音量，继续播放。
     *         AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 这个也是表明音请求的音频焦点持续时间比较短，但是在这段时间内，不希望任何应用(包括系统应用)来做任何与音频相关的事情，就算是降低音量播放音乐也是不被希望的。例如当我们进行录音或者语音识别的时候，我们不希望其他的声音出现干扰。
     *
     *
     */
    public void requestFocus(int mode) {

        int result;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (mFocusRequest == null) {
                if (mAudioAttributes == null) {
                    mAudioAttributes = new AudioAttributes.Builder()
                            .setUsage(AudioAttributes.USAGE_MEDIA)
                            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                            .build();
                }
                mFocusRequest = new AudioFocusRequest.Builder(mode)
                        .setAudioAttributes(mAudioAttributes)
                        .setWillPauseWhenDucked(true)
                        .setOnAudioFocusChangeListener(this)
                        .build();
            }
            result = mAudioManager.requestAudioFocus(mFocusRequest);
        } else {
            result = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, mode);
        }

        if (mOnRequestFocusResultListener != null) {
            mOnRequestFocusResultListener.onHandleResult(result);
        }
    }


    @Override
    public void onAudioFocusChange(int focusChange) {
        if (mAudioFocusChangeListener != null) {
            mAudioFocusChangeListener.onAudioFocusChange(focusChange);
        }
    }

    /**
     * 释放焦点
     */
    public void releaseAudioFocus() {

        if (mFocusRequest != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mAudioManager.abandonAudioFocusRequest(mFocusRequest);

                mFocusRequest = null;


            } else {
                mAudioManager.abandonAudioFocus(this);
            }
        }
    }

    /**
     * Handle the result of audio focus.
     */
    public interface onRequestFocusResultListener {
        void onHandleResult(int result);
    }

    public void setOnHandleResultListener(onRequestFocusResultListener listener) {
        mOnRequestFocusResultListener = listener;
    }


    /**
     * Same as AudioManager.OnAudioFocusChangeListener.
     */
    public interface OnAudioFocusChangeListener {
        void onAudioFocusChange(int focusChange);
    }


    public void setOnAudioFocusChangeListener(OnAudioFocusChangeListener listener) {
        mAudioFocusChangeListener = listener;
    }

}
